#ifndef MainObject_h
#define MainObject_h

#include "CCodeCounter.h"
#include "CCCounter.h"
#include "CJavaCounter.h"
#include "CCsharpCounter.h"
#include "CVbCounter.h"
#include "CWebCounter.h"
#include "CHtmlCounter.h"
#include "CJavascriptCounter.h"
#include "CPhpCounter.h"
#include "CAdaCounter.h"
#include "CSqlCounter.h"
#include "CPerlCounter.h"
#include "CCssCounter.h"
#include "CColdfusionCounter.h"


#define DUP_PAIRS_OUTFILE "DuplicatePairs.txt"

class MainObject
{
public:
	MainObject();
	~MainObject();
	int MainProcess(int argc, char *argv[]);
	string GetLangName(unsigned int class_type);
	static void show_usage (string program, bool do_exit = true);
	void progress(int disp, int count_progress, int sizeo);

protected:
	int ReadAllFile(StringVector &inputFileVector, string const &inputFileList = input_file_list_name, bool useListA = true);
	void ProcessSourceList(bool useListA = true);
	bool isSupportedFileExtension(string filename);
	unsigned int DecideLanguage(string file_name, bool setCounter = true);
	int PrintResults(bool useListA = true, string outputFileNamePrePend = "",
		StringVector* filesToPrint=NULL, bool excludeFiles = true);
	void PrintDuplicateSummary(bool useListA = true, string outputFileNamePrePend = "");
	void PrintDupList(StringVector& myList1, StringVector& myList2, ofstream& outfile);

	int PrintComplexityResults(bool useListA = true, string outputFileNamePrePend = "", bool printDuplicates = false);
	void ResetCounterCounts();

	typedef list<SourceFileElement> SourceFileList;

	// ------------------   Duplication Modification -----------------------
	int parse_commandLine(int argc, char *argv[]);
	void findDuplicateFiles(SourceFileList& fileList, StringVector& dupList1, StringVector& dupList2);
	bool findDuplicateFor(SourceFileList& compareList, SourceFileList::iterator& i,
		StringVector& dupList1, StringVector& dupList2);
	StringVector duplicateFilesInA1, duplicateFilesInA2, duplicateFilesInB1, duplicateFilesInB2;

	SourceFileList SourceFile;
	SourceFileList SourceFileB;

	// ------------------   Duplication Modification -----------------------
	double duplicate_threshold;
	vector <string>listFilesToBeSearched;

	size_t lsloc_truncate;	// 0=no truncation

	string dirnameA;
	string dirnameB;

	// clearCaseFile = true if the target files are extracted from the ClearCase CM
	bool clearCaseFile;

private:
	map<int,CCodeCounter*> CounterForEachLanguage;

	CCodeCounter* counter;

	struct TotalValue
	{
		TotalValue()
		{
			total_line = 0;
			blank_line = 0;
			whole_comment = 0;
			embed_comment = 0;
			phy_direct = 0;
			phy_decl = 0;
			phy_instr = 0;
			log_direct = 0;
			log_decl = 0;
			log_instr = 0;
			num_of_file = 0;
		}

		int total_line;
		int blank_line;
		int whole_comment;
		int embed_comment;
		int phy_direct;
		int phy_decl;
		int phy_instr;
		int log_direct;
		int log_decl;
		int log_instr;
		int num_of_file;
	};

	struct WebTotalValue
	{
		WebTotalValue()
		{
			total_line = 0;
			blank_line = 0;
			whole_comment = 0;
			embed_comment = 0;
			for(int i=0; i<5; i++)
			{
				phy_direct[i] = 0;
				phy_decl[i] = 0;
				phy_instr[i] = 0;
				log_direct[i] = 0;
				log_decl[i] = 0;
				log_instr[i] = 0;
			}
			num_of_file = 0;
		}

		int total_line;
		int blank_line;
		int whole_comment;
		int embed_comment;
		int phy_direct[5];
		int phy_decl[5];
		int phy_instr[5];
		int log_direct[5];
		int log_decl[5];
		int log_instr[5];
		int num_of_file;
	};
};

#endif
